package com.yourenbang.lingyun.transaction.web.service.impl.migrate;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.constants.Constant;
import com.yourenbang.lingyun.constants.enums.ChannelIdEnums;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.core.exception.BizRuntimeException;
import com.yourenbang.lingyun.core.util.BizAssertUtils;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.redis.RedisUtils;
import com.yourenbang.lingyun.domain.Merchant20;
import com.yourenbang.lingyun.domain.Merchant20Example;
import com.yourenbang.lingyun.mapper.Merchant20Mapper;
import com.yourenbang.lingyun.mapper.UserBaseExtMapper;
import com.yourenbang.lingyun.transaction.config.AcmTransactionParams;
import com.yourenbang.lingyun.transaction.web.domain.dto.migrate.kuaishou.QueryTableDateDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.migrate.kuaishou.QueryTablePageDTO;
import com.yourenbang.lingyun.transaction.web.domain.po.klks.PayMerchantPO;
import com.yourenbang.lingyun.transaction.web.domain.po.klks.PledgeCash;
import com.yourenbang.lingyun.transaction.web.service.migrate.MerchantBatchMigrateService;
import com.yourenbang.lingyun.transaction.web.service.migrate.MerchantMigrateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class MerchantBatchMigrateServiceImpl extends AbstractMigrateService implements MerchantBatchMigrateService {

    @Autowired
    private RedisUtils redis;
    @Autowired
    private AcmTransactionParams acmTransactionParams;
    @Autowired
    private UserBaseExtMapper userBaseExtMapper;
    @Autowired
    private Merchant20Mapper merchant20Mapper;
    @Autowired
    private CommonMigrateServiceImpl commonMigrateService;
    @Autowired
    private MerchantMigrateService merchantMigrateService;


    @Override
    public boolean migrateMerchantPage(QueryTablePageDTO dto) {

        String uri = "/query/pay/base/query/limit";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;
        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<PayMerchantPO> payMerchantPOS = jsonArray.toJavaList(PayMerchantPO.class);

        saveMerchant(payMerchantPOS);
        return true;
    }


    @Override
    public boolean migrateMerchantOrder(QueryTableDateDTO dto) {

        String uri = "/query/pay/base/query/order";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;


        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<PayMerchantPO> payMerchantPOS = jsonArray.toJavaList(PayMerchantPO.class);

        updateMerchant(payMerchantPOS);
        return true;
    }

    @Override
    public boolean migratePledgePage(QueryTablePageDTO dto) {
        String uri = "/query/pay/base/query/limit";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;
        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<PledgeCash> pledgeCashPOS = jsonArray.toJavaList(PledgeCash.class);

        updatePledge(pledgeCashPOS);
        return true;
    }

    private void updatePledge(List<PledgeCash> pledgeCashes) {

        for (PledgeCash pledgeCash : pledgeCashes) {
            try {
                String userBaseId = getUserBaseId(userBaseExtMapper, pledgeCash.getUserId(), redis);
                if (StringUtils.isBlank(userBaseId)) {
                    KLog.error("[商户-考拉快收-押金迁移]押金更新,未获取到凌云用户id,入参:{}", pledgeCash.toJSON());
                    throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未获取到凌云用户id");
                }
                Merchant20Example oldMerchant20Example = new Merchant20Example();
                oldMerchant20Example.createCriteria()
                        .andUserBaseIdEqualTo(userBaseId)
                        .andChannelIdEqualTo(ChannelIdEnums.convertKuaiShouProductType(pledgeCash.getProductType()).getCode())
                        .andPlatNoEqualTo(PlatNoEnums.KLKS.getCode());

                List<Merchant20> oldMerchant20List = merchant20Mapper.selectByExample(oldMerchant20Example);
                if (CollectionUtils.isEmpty(oldMerchant20List)) {
                    Merchant20Example eposMerchant20Example = new Merchant20Example();
                    if (StringUtils.equals(pledgeCash.getProductType(),"05")) {
                        eposMerchant20Example.createCriteria()
                                .andUserBaseIdEqualTo(userBaseId)
                                .andChannelIdEqualTo(ChannelIdEnums.convertKuaiShouProductType("08").getCode())
                                .andPlatNoEqualTo(PlatNoEnums.KLKS.getCode());
                    } else if (StringUtils.equals(pledgeCash.getProductType(),"08")){
                        eposMerchant20Example.createCriteria()
                                .andUserBaseIdEqualTo(userBaseId)
                                .andChannelIdEqualTo(ChannelIdEnums.convertKuaiShouProductType("05").getCode())
                                .andPlatNoEqualTo(PlatNoEnums.KLKS.getCode());
                    }else {
                        KLog.info("[商户-考拉快收-数据迁移]押金更新,未找到原通道商户数据,插入押金数据,入参:{}", pledgeCash.toJSON());
                        throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未找到原通道商户数据");
                    }
                    List<Merchant20> eposMerchant20List = merchant20Mapper.selectByExample(eposMerchant20Example);
                    if (CollectionUtils.isEmpty(eposMerchant20List)){
                        KLog.info("[商户-考拉快收-数据迁移]押金更新,未找到原通道商户数据,插入押金数据,入参:{}", pledgeCash.toJSON());
                        throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未找到原通道商户数据");
                    }else {
                       oldMerchant20List = eposMerchant20List;
                    }
                }

                Merchant20 oldMerchant20 = oldMerchant20List.get(0);
                Merchant20 merchant20 = merchantMigrateService.fmtPledgeCashData(pledgeCash);
                merchant20.setMerchantId(oldMerchant20.getMerchantId());
                merchant20.setPledgeCashPayType(new Short("100"));
                int upCount = merchant20Mapper.updateByPrimaryKeySelective(merchant20);
                BizAssertUtils.assertOne(upCount, "更新通道商户失败");

            } catch (Exception e) {
                KLog.error("更新押金表失败,押金数据:{}", pledgeCash, e);
            }
        }
    }

    @Override
    public boolean migratePledgeOrder(QueryTableDateDTO dto) {
        String uri = "/query/pay/base/query/order";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;
        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<PledgeCash> pledgeCashPOS = jsonArray.toJavaList(PledgeCash.class);

        updatePledge(pledgeCashPOS);
        return true;
    }

    /**
     * 批量插入商户
     *
     * @param payMerchantPOS
     */
    private void saveMerchant(List<PayMerchantPO> payMerchantPOS) {
        List<Merchant20> merchant20s = new ArrayList<>();
        for (PayMerchantPO payMerchantPO : payMerchantPOS) {
            try {
                String userBaseId = getUserBaseId(userBaseExtMapper, payMerchantPO.getUserId(), redis);
                Merchant20 merchant20 = merchantMigrateService.fmtMerchantData(payMerchantPO, userBaseId);
                merchant20s.add(merchant20);
            } catch (Exception e) {
                KLog.error("迁移商户失败,商户:{}", payMerchantPO, e);
            }
        }
        if (merchant20s.size() != 0) {
            int i = merchant20Mapper.batchInsert(merchant20s);
            KLog.info("更新{}条商户结束", i);
        }
    }


    private void updateMerchant(List<PayMerchantPO> payMerchantPOS) {
        List<Merchant20> insertMerchant20s = new ArrayList<>();
        for (PayMerchantPO payMerchantPO : payMerchantPOS) {
            //查询商户如果存在执行下一位,不存在就插入 userbaseid,channelid,platno

            try {
                Merchant20Example example = new Merchant20Example();

                String userBaseId = getUserBaseId(userBaseExtMapper, payMerchantPO.getUserId(), redis);
                example.createCriteria().andUserBaseIdEqualTo(userBaseId)
                        .andChannelIdEqualTo(ChannelIdEnums
                                .convertKuaiShouProductType(payMerchantPO.getProductType()).getCode())
                        .andPlatNoEqualTo(PlatNoEnums.KLKS.getCode())
                        .andIsDelEqualTo(Constant.NORMAL);

                List<Merchant20> merchant20s = merchant20Mapper.selectByExample(example);
                //查不到插入,查到更新
                Merchant20 merchant20 = merchantMigrateService.fmtMerchantData(payMerchantPO, userBaseId);
                if (merchant20s.isEmpty()) {
                    insertMerchant20s.add(merchant20);
                } else {
                    merchant20.setMerchantId(merchant20s.get(0).getMerchantId());
                    int i = merchant20Mapper.updateByPrimaryKeySelective(merchant20);
                    BizAssertUtils.assertOne(i, "更新商户失败");
                }
            } catch (Exception e) {
                KLog.error("迁移商户失败,商户:{}", payMerchantPO, e);
            }
        }
        if (insertMerchant20s.size() != 0) {
            int i = merchant20Mapper.batchInsert(insertMerchant20s);
            KLog.info("[按时间更新商户]插入了商户{}条", i);
        }

    }
}
